package it.mouseclient;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Activity which displays a login screen to the user, offering registration as
 * well.
 */
public class LoginActivity extends Activity {

	private UDPClient client;
	/**
	 * Keep track of the login task to ensure we can cancel it if requested.
	 */
	private UserLoginTask mAuthTask = null;
	private String mPassword;
	private String mIPAddress;
	private int mPort;

	// UI references.
	private EditText mPasswordView;
	private EditText mIPAddressView;
	private EditText mPortView;
	private Button mConnectButton;
	private ProgressDialog mProgressDialog;
	private TextView mTextViewTitle;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);



		setContentView(R.layout.activity_login);

		mPasswordView = (EditText) findViewById(R.id.password);
		mPasswordView
				.setOnEditorActionListener(new TextView.OnEditorActionListener() {
					@Override
					public boolean onEditorAction(TextView textView, int id,
							KeyEvent keyEvent) {
						if (id == R.id.login || id == EditorInfo.IME_NULL) {
							attemptLogin();
							return true;
						}
						return false;
					}
				});

		mIPAddressView = (EditText) findViewById(R.id.address);

		mPortView = (EditText) findViewById(R.id.port);

		mConnectButton = (Button) findViewById(R.id.connect_button);
		mConnectButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				attemptLogin();
			}
		});

		mTextViewTitle = (TextView) findViewById(R.id.textViewTitle);
		Typeface titleFont = Typeface.createFromAsset(getAssets(),
				"fonts/orange juice.ttf");
		mTextViewTitle.setTypeface(titleFont);

		// hide keyboard :
		getWindow().setSoftInputMode(
				WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
		// mConnectButton.setFocusableInTouchMode(true);
		// mConnectButton.requestFocus();
		
		//Rimuovo la tastiera quando clicco al di fuori delle TextView
		ScrollView view = (ScrollView) findViewById(R.id.login_form);
		view.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				InputMethodManager imm = (InputMethodManager) LoginActivity.this.getSystemService(
                        android.content.Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(LoginActivity.this.getCurrentFocus().getWindowToken(), 0);
                return false;
			}
		});
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		String pkg = getPackageName() + ".";
		outState.putString(pkg + R.string.address_id, mIPAddress);
		outState.putInt(pkg + R.string.port_id, mPort);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		getMenuInflater().inflate(R.menu.activity_login, menu);
		return true;
	}
	
	@Override
	public void onRestoreInstanceState(Bundle savedInstanceState){
		super.onRestoreInstanceState(savedInstanceState);
		String pkg = getPackageName() + ".";
		if (savedInstanceState != null && savedInstanceState.containsKey(pkg + R.string.address_id))
			mIPAddress = savedInstanceState
					.getString(pkg + R.string.address_id);
		else
			mIPAddress = "";
		if (savedInstanceState != null && savedInstanceState.containsKey(pkg + R.string.port_id))
			mPort = savedInstanceState.getInt(pkg + R.string.port_id);
		else
			mPort = 0;
	}
	
	@Override
	public void onResume(){
		super.onResume();
		mIPAddressView.setText(mIPAddress);
		if (mPort > 0)
			mPortView.setText(mPort+"");
	}
	

	/**
	 * Attempts to sign in or register the account specified by the login form.
	 * If there are form errors (invalid email, missing fields, etc.), the
	 * errors are presented and no actual login attempt is made.
	 */
	public void attemptLogin() {
		if (mAuthTask != null) {
			return;
		}

		// Reset errors.
		mPasswordView.setError(null);
		mIPAddressView.setError(null);
		mPortView.setError(null);

		// Store values at the time of the login attempt.
		mPassword = mPasswordView.getText().toString();
		mIPAddress = mIPAddressView.getText().toString();
		if (!mPortView.getText().toString().equals("")) {
			mPort = Integer.parseInt(mPortView.getText().toString());
		} else
			mPort = 0;

		boolean cancel = false;
		View focusView = null;

		// Check for a valid password.
		if (TextUtils.isEmpty(mPassword)) {
			mPasswordView.setError(getString(R.string.error_field_required));
			focusView = mPasswordView;
			cancel = true;
		} else if (mPassword.length() < 4) {
			mPasswordView.setError(getString(R.string.error_invalid_password));
			focusView = mPasswordView;
			cancel = true;
		}

		if (mPort < 1 || mPort > 65535) {
			mPortView.setError(getString(R.string.error_invalid_port));
			focusView = mPortView;
			cancel = true;
		}

		if (TextUtils.isEmpty(mIPAddress)
				|| !mIPAddress
						.matches("[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}")) {
			mIPAddressView.setError(getString(R.string.error_invalid_address));
			focusView = mIPAddressView;
			cancel = true;
		}

		if (cancel) {
			// There was an error; don't attempt login and focus the first
			// form field with an error.
			focusView.requestFocus();
		} else {
			// Show a progress spinner, and kick off a background task to
			// perform the user login attempt.
			showProgress(true);
			mAuthTask = new UserLoginTask();
			mAuthTask.execute((Void) null);
		}
	}

	/**
	 * Shows the progress UI and hides the login form.
	 */
	private void showProgress(final boolean show) {
		if (show) {
			mProgressDialog = ProgressDialog.show(this, "Sign in",
					"Connecting...");
		} else {
			mProgressDialog.dismiss();
		}
	}

	private boolean connect() {
		boolean c = false;
		try {
			client = new UDPClient(InetAddress.getByName(mIPAddress), mPort);
			client.open();
			c = true;
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return c;
	}

	/**
	 * Represents an asynchronous login/registration task used to authenticate
	 * the user.
	 */
	public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
		@Override
		protected Boolean doInBackground(Void... params) {
			// TODO: attempt authentication against a network service.
			boolean success = false;
			if (connect()) {
				success = client.doLogin(mPassword);
				if (success)
					client.close(true);
			}
			return success;
		}

		@Override
		protected void onPostExecute(final Boolean success) {
			mAuthTask = null;

			if (success) {
				String pkg = getPackageName() + ".";
				Intent touchpadIntent = new Intent(getApplicationContext(),
						TouchpadActivity.class);
				Bundle b = new Bundle();
				b.putString(pkg + R.string.address_id, mIPAddress);
				b.putInt(pkg + R.string.port_id, mPort);
				b.putString(pkg + R.string.password_id, mPassword);
				touchpadIntent.putExtra(pkg + R.string.connection_param_id, b);
				startActivity(touchpadIntent);
				showProgress(false);
			} else {
				showProgress(false);
				Toast t = Toast.makeText(LoginActivity.this,
						R.string.error_connection, Toast.LENGTH_LONG);
				t.show();
			}

		}

		@Override
		protected void onCancelled() {
			mAuthTask = null;
			showProgress(false);
		}
	}
}
